/* ----------------------------------------------------------------------
*
* Copyright (C) 2024 XiaoFei. All rights reserved.
*
* $file:        XiaoFei_Matrix.h
* $Date:        28-October-2024
* $Revision:    V1.2
* $Project:     XiaoFei DSP Library
*
* -------------------------------------------------------------------- */

#ifndef __XiaoFei_Matrix_H
#define __XiaoFei_Matrix_H

#ifndef My_ERROR
#define My_ERROR                    0.00000001
#endif
#ifndef My_PI
#define My_PI                       3.14159265
#endif
#ifndef My_EXP_2
#define My_EXP_2                    7.38905609
#endif
#ifndef My_EXP_5
#define My_EXP_5                    148.41315915
#endif
#ifndef My_LOG_2
#define My_LOG_2                    0.69314718
#endif
#ifndef My_LOG_10
#define My_LOG_10                   2.30258509
#endif

#ifndef ResStatus_TypeDef_def
#define ResStatus_TypeDef_def
typedef enum
{ 
    Error       = 0x00,         /*!< The calculation failed */
    Success     = 0x01          /*!< The calculation was successful */
}ResStatus_TypeDef;
#endif

#ifndef Matrix_TypeDef_def
#define Matrix_TypeDef_def
typedef struct {
    double** Val;               /*!< The first address of the Matrix. */
    unsigned int Rows;          /*!< The rows of the vector */
    unsigned int Cols;          /*!< The cols of the vector */
}Matrix_TypeDef; 
#endif

/*
* @function:    My_MatrixCreate
* @parameter:   [in]    *rows           The rows of the matrix.
* @parameter:   [in]    *input          The cols of the matrix.
* @return:      The matrix memory applied to storage vectors.
*/
Matrix_TypeDef My_MatrixCreate(unsigned int rows, unsigned int cols, double* data);

/*
* @function:    My_MatrixFree
* @parameter:   [in]    *mat            The first address of the input matrix.
* @return:      None.
*/
void My_MatrixFree(Matrix_TypeDef* mat);

/*
* @function:    My_MatrixAdd
* @parameter:   [in]    *inputa         The first address of the input matrix.
* @parameter:   [in]    *inputb         The first address of another input matrix.
* @parameter:   [out]   *output         The first address of the output matrix based on matrix additions.
* @return:      Successes or failures of the results of the calculations.
*/
ResStatus_TypeDef My_MatrixAdd(Matrix_TypeDef* inputa, Matrix_TypeDef* inputb, Matrix_TypeDef* output);

/*
* @function:    My_MatrixSub
* @parameter:   [in]    *inputa         The first address of the input matrix.
* @parameter:   [in]    *inputb         The first address of another input matrix.
* @parameter:   [out]   *output         The first address of the output matrix based on matrix subtraction.
* @return:      Successes or failures of the results of the calculations.
*/
ResStatus_TypeDef My_MatrixSub(Matrix_TypeDef* inputa, Matrix_TypeDef* inputb, Matrix_TypeDef* output);

/* 
* @function:    My_MatrixScale
* @parameter:   [in]    *input          The first address of the input matrix.
* @parameter:   [in]    a               The scale of the multiplication operation.
* @parameter:   [out]   *output         The first address of the output vector based on matrix Scale.
* @return:      Successes or failures of the results of the calculations.
*/
ResStatus_TypeDef My_MatrixScale(Matrix_TypeDef* input, double a, Matrix_TypeDef* output);

/*
* @function:    My_MatrixMul
* @parameter:   [in]    *inputa         The first address of the input matrix.
* @parameter:   [in]    *inputb         The first address of another input matrix.
* @parameter:   [out]   *output         The first address of the output matrix based on matrix multiplication.
* @return:      Successes or failures of the results of the calculations.
*/
ResStatus_TypeDef My_MatrixMul(Matrix_TypeDef* inputa, Matrix_TypeDef* inputb, Matrix_TypeDef* output);

/*
* @function:    My_MatrixTran
* @parameter:   [in]    *input          The first address of the input matrix.
* @parameter:   [out]   *output         The first address of the output matrix based on matrix Transpose.
* @return:      Successes or failures of the results of the calculations.
*/
ResStatus_TypeDef My_MatrixTran(Matrix_TypeDef* input, Matrix_TypeDef* output);

/*
* @function:    My_MatrixConv
* @parameter:   [in]    *input          The first address of the input matrix.
* @parameter:   [in]    *core           The first address of the convolution core matrix.
* @parameter:   [out]   *output         The first address of the output matrix based on matrix convolution.
* @return:      Successes or failures of the results of the calculations.
*/
ResStatus_TypeDef My_MatrixConv(Matrix_TypeDef* input, Matrix_TypeDef* core, Matrix_TypeDef* output);

/*
* @function:    My_MatrixInve
* @parameter:   [in]    *input          The first address of the input matrix.
* @parameter:   [out]   *output         The first address of the output matrix based on matrix inverse.
* @return:      Successes or failures of the results of the calculations.
*/
ResStatus_TypeDef My_MatrixInve(Matrix_TypeDef* input, Matrix_TypeDef* output);

/*
* @function:    My_MatrixDet
* @parameter:   [in]    *input          The first address of the input matrix.
* @parameter:   [out]   *output         The address of the determinant of the matrix.
* @return:      Successes or failures of the results of the calculations.
*/
ResStatus_TypeDef My_MatrixDet(Matrix_TypeDef* input, double* output);

#endif

